package ngocthien.game;

import java.util.ArrayList;
import java.util.List;

import javax.microedition.khronos.opengles.GL10;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.BoundCamera;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.camera.hud.controls.DigitalOnScreenControl;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTile;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
import org.anddev.andengine.entity.modifier.IEntityModifier;
import org.anddev.andengine.entity.modifier.PathModifier;
import org.anddev.andengine.entity.modifier.PathModifier.Path;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.font.Font;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.opengl.util.GLHelper;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.constants.Constants;
import org.anddev.andengine.util.path.astar.AStarPathFinder;



import android.content.Context;
import android.content.pm.ActivityInfo;
import android.opengl.GLU;

public class StateGame extends BaseGameActivity implements
		IOnSceneTouchListener {

	// ===========================================================
	// Fields
	// ===========================================================

	// Engine Fields
	protected static Scene mScene;
	protected static BoundCamera mBoundChaseCamera;

	// Texture Fields
	private BitmapTextureAtlas mTexturePlayer;
	protected static TiledTextureRegion mPlayerTextureRegion;
	protected static BitmapTextureAtlas mOnScreenControlTexture;
	protected static TextureRegion mOnScreenControlBaseTextureRegion;
	protected static TextureRegion mOnScreenControlKnobTextureRegion;
	private BitmapTextureAtlas FadeTexture;
	private TextureRegion FadeTextureRegion;

	// Sprite Control/UI/Pathing Fields
	protected static DigitalOnScreenControl mDigitalOnScreenControl;
	protected static AnimatedSprite player;
	protected static int playerSpawnDirection;
	protected static org.anddev.andengine.util.path.Path A_path;
	protected static AStarPathFinder<TMXLayer> finder;
	protected static float[] playerFootCordinates;
	protected static Path mCurrentPath;
	protected static boolean isWalking;
	protected static int mWaypointIndex;
	protected static PathModifier mMoveModifier;
	protected static IEntityModifier mPathTemp;

	// TMX Fields
	protected static TMXLoader tmxLoader;
	protected static TMXTiledMap mTMXTiledMap;
	protected static TMXTiledMap mLargeTMXMap;
	protected static TMXLayer TMXMapLayer;
	protected static TMXLayer mTopLayer;
	protected static TMXLayer mAnimateLayer;
	protected static TMXTile playerLocationTile;

	// Lists
	protected static List<TMXTile> CollideTiles;
	protected static List<TMXTile> ExitTiles;
	protected static ArrayList<Integer> MapNumber;
	protected static List<TMXTile> animatedTiles;
	protected static List<TMXTile> playerSpawnTiles;
	protected static ArrayList<Integer> LinkNumber;
	protected static List<TMXTile> propertyTiles;
	protected static ArrayList<Integer> propertyIndex;

	// Indexes
	protected static int mCurrentMapIndex;
	protected static int mLargeTMXIndex = 1000;
	protected static int mLinkIndex;

	// Initial values; These should be initialized from a separate file that was
	// saved before finish();
	protected static float InitialplayerSpawnX = Global.TILE_WIDTH * 10;
	protected static float InitialplayerSpawnY = Global.TILE_HEIGHT * 5;

	// Used to get object tiles in TMX
	protected static int ObjectX;
	protected static int ObjectY;
	protected static int ObjectWidth;
	protected static int ObjectHeight;

	// Boolean Flags
	protected static boolean EnableBounds = true;
	protected static boolean AssetsAttached;
	protected static boolean MapIsLoading;
	protected static boolean TouchOnce;
	protected static boolean UpdateTiles;

	// Misc.
	protected static Sprite FadeScreen;
	protected static Context mContext;

	public Engine onLoadEngine() {
		// TODO Auto-generated method stub
		this.mBoundChaseCamera = new BoundCamera(0, 0, Global.CAMERA_WIDTH,
				Global.CAMERA_HEIGHT) {

			private void onApplySceceMatrix(GL10 pGL) {
				// TODO Auto-generated method stub
				GLHelper.setProjectionIdentityMatrix(pGL);
				GLU.gluOrtho2D(pGL, this.getMinX(), this.getMaxX(),
						this.getMaxX(), this.getMaxY());

			}
		};

		getApplicationContext();

		final EngineOptions engineOptions = new EngineOptions(true,
				ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(
						Global.CAMERA_WIDTH, Global.CAMERA_HEIGHT),
				this.mBoundChaseCamera);

		engineOptions.getTouchOptions().setRunOnUpdateThread(true);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		Engine engine = new Engine(engineOptions);
		return engine;
	}

	public void onLoadResources() {
		// TODO Auto-generated method stub
		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

		// Control texture
		StateGame.mOnScreenControlTexture = new BitmapTextureAtlas(256, 128,
				TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		StateGame.mOnScreenControlBaseTextureRegion = BitmapTextureAtlasTextureRegionFactory
				.createFromAsset(StateGame.mOnScreenControlTexture, this,
						"onscreen_control_base.png", 0, 0);
		StateGame.mOnScreenControlKnobTextureRegion = BitmapTextureAtlasTextureRegionFactory
				.createFromAsset(StateGame.mOnScreenControlTexture, this,
						"onscreen_control_knob.png", 128, 0);

		// Player sprite texture
		this.mTexturePlayer = new BitmapTextureAtlas(128, 128,
				TextureOptions.DEFAULT);
		StateGame.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory
				.createTiledFromAsset(this.mTexturePlayer, this, "hero.png", 0,
						0, 3, 4);

		this.FadeTexture = new BitmapTextureAtlas(1024, 1024,
				TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.FadeTextureRegion = BitmapTextureAtlasTextureRegionFactory
				.createFromAsset(this.FadeTexture, getApplicationContext(),
						"FadeBackground.png", 0, 0);
		this.mEngine.getTextureManager().loadTextures(this.mTexturePlayer,
				StateGame.mOnScreenControlTexture, this.FadeTexture);
	}

	public Scene onLoadScene() {
		// Logs the FPS in logCat
		this.mEngine.registerUpdateHandler(new FPSLogger());

		// Initializes the scene
		mScene = new Scene();

		// Sets the background to black. Parameters control red, blue, and green
		// (f means the digit is a fraction)
		mScene.setBackground(new ColorBackground(0f, 0f, 0f));

		// Initializes the TMXLoader
		tmxLoader = new TMXLoader(this, this.mEngine.getTextureManager(),
				TextureOptions.NEAREST, null);

		FadeScreen = new Sprite(0, 0, FadeTextureRegion);

		// Initial load. In real game the current map index would be saved right
		// before exiting and that index would be passed into this method
//		TMXMapUpdater.loadAndAttachAssets(0);

		mScene.registerUpdateHandler(new IUpdateHandler() {

			public void reset() {
			}

			public void onUpdate(final float pSecondsElapsed) {

				// Allows the tiles to get the player location as soon as
				// possible
				if (UpdateTiles) {

					// Get the scene-coordinates of the tile center.
					playerFootCordinates = player
							.convertLocalToSceneCoordinates(16, 16);

					// Get the tile where the center of the current tile is.
					playerLocationTile = TMXMapLayer.getTMXTileAt(
							playerFootCordinates[Constants.VERTEX_INDEX_X],
							playerFootCordinates[Constants.VERTEX_INDEX_Y]);
				}

				// If the TMX map is loading then the scene updates will freeze
				if (!MapIsLoading) {

					// Gets the index of the current map
					mCurrentMapIndex = Integer.parseInt(mTMXTiledMap
							.getTMXTiledMapProperties().get(0).getValue());

					// This updates the TMX map when the sprite exits or enters
					// the scene
//					TMXMapUpdater.updateTMXMap();
				}
			}
		});

		// This deals with tile animation
		// mScene.registerUpdateHandler(new TimerHandler(TILE_ANIMATION_SPEED,
		// true, new ITimerCallback() {
		//
		// public void onTimePassed(final TimerHandler pTimerHandler) {
		//
		// if (!MapIsLoading) {
		//
		// //Do the random property
		// TMXMapUpdater.doProperty1(playerLocationTile);
		//
		// TMXMapUpdater.doTileAnimations();
		//
		// }
		// }
		// }));

		// If the options have been set to enable Touch then allow the scene to
		// accept touch events
//		if (Options.TouchEnabled) {
//			mScene.setOnSceneTouchListener(this);
//		}

		return mScene;
	}

	public void onLoadComplete() {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener#
	 * onSceneTouchEvent(org.anddev.andengine.entity.scene .Scene,
	 * org.anddev.andengine.input.touch.TouchEvent)
	 */
	public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
		// TODO Auto-generated method stub
		if (!MapIsLoading) {
			if (pSceneTouchEvent.isActionDown()
					&& pSceneTouchEvent.getX() < TMXMapLayer.getWidth()
					&& pSceneTouchEvent.getY() < TMXMapLayer.getHeight()
					&& pSceneTouchEvent.getX() > 0
					&& pSceneTouchEvent.getY() > 0 && TouchOnce) {

				// Walks to the touched area
//				UI.walkTo(pSceneTouchEvent.getX(), pSceneTouchEvent.getY(),
//						pScene);

				// This is set to true in the GeneralUI
				TouchOnce = false;

				return true;
			}
		}
		return false;
	}
}
